package com.datdo.mobilib.cache; import android.util.Pair; import com.datdo.mobilib.util.MblUtils; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; /** * <pre> * An extension of {@link MblCacheMaster}. All requests via get() methods are accumulated in a list and are executed at once every 100 milliseconds. * </pre> */ public abstract class MblPendingCacheMaster<T> extends MblCacheMaster<T> { /** * Contructor. * @param type class of objects * @param duration time in milliseconds before an object become expired */ public MblPendingCacheMaster(Class<T> type, long duration) { super(type, duration); MblUtils.repeatDelayed(new Runnable() { @Override public void run() { runAll(); } }, 100); } private List<Pair<List<String>, MblGetManyCallback>> mPendingRequests = Collections.synchronizedList(new ArrayList<Pair<List<String>, MblGetManyCallback>>()); @Override public Runnable get(final List<String> ids, MblGetManyCallback<T> callback) { if (MblUtils.isEmpty(ids)) { return super.get(ids, callback); } mPendingRequests.add(new Pair<List<String>, MblGetManyCallback>(ids, callback)); return new Runnable() { @Override public void run() { mPendingRequests.remove(ids); } }; } private void runAll() { if (mPendingRequests.isEmpty()) { return; } final Set<String> allIds = new HashSet<>(); final List<Pair<List<String>, MblGetManyCallback>> pendingRequests = new ArrayList<>(mPendingRequests); mPendingRequests.clear(); for (Pair<List<String>, MblGetManyCallback> p : pendingRequests) { allIds.addAll(p.first); } super.get(new ArrayList<>(allIds), new MblGetManyCallback<T>() { @Override public void onSuccess(List<T> objects) { Map<String, T> idToObject = new HashMap<>(); for (T o : objects) { idToObject.put(getObjectId(o), o); } for (Pair<List<String>, MblGetManyCallback> p : pendingRequests) { List<T> results = new ArrayList<T>(); MblGetManyCallback callback = p.second; for (String id : p.first) { T o = idToObject.get(id); if (o != null) { results.add(o); } } if (callback != null) { callback.onSuccess(results); } } } @Override public void onError() { for (Pair<List<String>, MblGetManyCallback> p : pendingRequests) { MblGetManyCallback callback = p.second; if (callback != null) { callback.onError(); } } } }); } }